home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / glibc108.gz / glibc108 / glibc-1.08.1 / hurd / dtable.c < prev    next >
C/C++ Source or Header  |  1994-05-30  |  7KB  |  258 lines

  1. /* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <hurd.h>
  21. #include <hurd/term.h>
  22. #include <hurd/fd.h>
  23. #include <gnu-stabs.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <fcntl.h>
  27. #include <limits.h>
  28. #include <cthreads.h>        /* For `struct mutex'.  */
  29. #include "set-hooks.h"
  30. #include "hurdmalloc.h"        /* XXX */
  31.  
  32.  
  33. struct mutex _hurd_dtable_lock;
  34. struct hurd_fd **_hurd_dtable;
  35. int _hurd_dtablesize;
  36.  
  37.  
  38. DEFINE_HOOK (_hurd_fd_subinit, (void));
  39.  
  40. /* Initialize the file descriptor table at startup.  */
  41.  
  42. static void
  43. init_dtable (void)
  44. {
  45.   register size_t i;
  46.  
  47.   __mutex_init (&_hurd_dtable_lock);
  48.  
  49.   /* The initial size of the descriptor table is that of the passed-in
  50.      table.  It will be expanded as necessary up to _hurd_dtable_rlimit.  */
  51.   _hurd_dtablesize = _hurd_init_dtablesize;
  52.  
  53.   /* Allocate the vector of pointers.  */
  54.   _hurd_dtable = malloc (_hurd_dtablesize * sizeof (*_hurd_dtable));
  55.   if (_hurd_dtablesize != 0 && _hurd_dtable == NULL)
  56.     __libc_fatal ("hurd: Can't allocate file descriptor table\n");
  57.  
  58.   /* Initialize the descriptor table.  */
  59.   for (i = 0; i < _hurd_init_dtablesize; ++i)
  60.     {
  61.       if (_hurd_init_dtable[i] == MACH_PORT_NULL)
  62.     /* An unused descriptor is marked by a null pointer.  */
  63.     _hurd_dtable[i] = NULL;
  64.       else
  65.     {
  66.       /* Allocate a new file descriptor structure.  */
  67.       struct hurd_fd *new = malloc (sizeof (struct hurd_fd));
  68.       if (new == NULL)
  69.         __libc_fatal ("hurd: Can't allocate initial file descriptors\n");
  70.  
  71.       /* Initialize the port cells.  */
  72.       _hurd_port_init (&new->port, MACH_PORT_NULL);
  73.       _hurd_port_init (&new->ctty, MACH_PORT_NULL);
  74.  
  75.       /* Install the port in the descriptor.
  76.          This sets up all the ctty magic.  */
  77.       _hurd_port2fd (new, _hurd_init_dtable[i], 0);
  78.  
  79.       _hurd_dtable[i] = new;
  80.     }
  81.     }
  82.  
  83.   /* Clear out the initial descriptor table.
  84.      Everything must use _hurd_dtable now.  */
  85.   __vm_deallocate (__mach_task_self (),
  86.            (vm_address_t) _hurd_init_dtable,
  87.            _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0]));
  88.   _hurd_init_dtable = NULL;
  89.   _hurd_init_dtablesize = 0;
  90.  
  91.   /* Initialize the remaining empty slots in the table.  */
  92.   for (; i < _hurd_dtablesize; ++i)
  93.     _hurd_dtable[i] = NULL;
  94.  
  95.   /* Run things that want to run after the file descriptor table
  96.      is initialized.  */
  97.   RUN_HOOK (_hurd_fd_subinit, ());
  98. }
  99.  
  100. text_set_element (_hurd_subinit, init_dtable);
  101.  
  102. /* XXX when the linker supports it, the following functions should all be
  103.    elsewhere and just have text_set_elements here.  */
  104.  
  105. /* Called by `getdport' to do its work.  */
  106.  
  107. static file_t
  108. get_dtable_port (int fd)
  109. {
  110.   file_t dport;
  111.   int err = HURD_DPORT_USE (fd, __mach_port_mod_refs (__mach_task_self (),
  112.                               (dport = ctty ?: port),
  113.                               MACH_PORT_RIGHT_SEND,
  114.                               1));
  115.   if (err)
  116.     {
  117.       errno = err;
  118.       return MACH_PORT_NULL;
  119.     }
  120.   else
  121.     return dport;
  122. }
  123.  
  124. file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port;
  125.  
  126. #include <hurd/signal.h>
  127.  
  128. /* We are in the child fork; the dtable lock is still held.
  129.    The parent has inserted send rights for all the normal io ports,
  130.    but we must recover ctty-special ports for ourselves.  */
  131. static error_t
  132. fork_child_dtable (void)
  133. {
  134.   error_t err;
  135.   int i;
  136.  
  137.   err = 0;
  138.  
  139.   for (i = 0; !err && i < _hurd_dtablesize; ++i)
  140.     {
  141.       struct hurd_fd *d = _hurd_dtable[i];
  142.  
  143.       /* No other thread is using the send rights in the child task.  */
  144.       d->port.users = d->ctty.users = NULL;
  145.  
  146.       if (d->ctty.port)
  147.     /* There was a ctty-special port in the parent.
  148.        We need to get one for ourselves too.  */
  149.       err = __term_become_ctty (d->ctty.port,
  150.                     /* XXX no guarantee that init_pids hook
  151.                        has been run BEFORE this one! */
  152.                     _hurd_pid, _hurd_pgrp, _hurd_msgport,
  153.                     &d->port.port);
  154.  
  155.       /* XXX for each fd with a cntlmap, reauth and re-map_cntl.  */
  156.     }
  157.   return err;
  158. }
  159.  
  160. data_set_element (_hurd_fork_locks, _hurd_dtable_lock);
  161. text_set_element (_hurd_fork_child_hook, fork_child_dtable);
  162.  
  163. /* Called when our process group has changed.  */
  164.  
  165. static void
  166. ctty_new_pgrp (void)
  167. {
  168.   int i;
  169.   
  170.   HURD_CRITICAL_BEGIN;
  171.   __mutex_lock (&_hurd_dtable_lock);
  172.  
  173.   for (i = 0; i < _hurd_dtablesize; ++i)
  174.     {
  175.       struct hurd_fd *const d = _hurd_dtable[i];
  176.       struct hurd_userlink ulink, ctty_ulink;
  177.       io_t port, ctty;
  178.  
  179.       if (d == NULL)
  180.     /* Nothing to do for an unused descriptor cell.  */
  181.     continue;
  182.  
  183.       port = _hurd_port_get (&d->port, &ulink);
  184.       ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
  185.  
  186.       if (ctty)
  187.     {
  188.       /* This fd has a ctty-special port.  We need a new one, to tell
  189.              the io server of our different process group.  */
  190.       io_t new;
  191.       if (! __term_become_ctty (ctty, _hurd_pid, _hurd_pgrp, _hurd_msgport,
  192.                     &new))
  193.         _hurd_port_set (&d->port, new);
  194.     }
  195.  
  196.       _hurd_port_free (&d->port, &ulink, port);
  197.       _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
  198.     }
  199.  
  200.   __mutex_unlock (&_hurd_dtable_lock);
  201.   HURD_CRITICAL_END;
  202. }
  203.  
  204. text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp);
  205.  
  206. /* Called to reauthenticate the dtable when the auth port changes.  */
  207.  
  208. static void
  209. reauth_dtable (void)
  210. {
  211.   int i;
  212.  
  213.   HURD_CRITICAL_BEGIN;
  214.   __mutex_lock (&_hurd_dtable_lock);
  215.  
  216.   for (i = 0; i < _hurd_dtablesize; ++i)
  217.     {
  218.       struct hurd_fd *const d = _hurd_dtable[i];
  219.       mach_port_t new, newctty;
  220.       
  221.       if (d == NULL)
  222.     /* Nothing to do for an unused descriptor cell.  */
  223.     continue;
  224.  
  225.       /* Take the descriptor cell's lock.  */
  226.       __spin_lock (&d->port.lock);
  227.       
  228.       /* Reauthenticate the descriptor's port.  */
  229.       if (d->port.port != MACH_PORT_NULL &&
  230.       ! __io_reauthenticate (d->port.port, _hurd_pid) &&
  231.       ! __USEPORT (AUTH, __auth_user_authenticate (port,
  232.                                d->port.port, _hurd_pid,
  233.                                &new)))
  234.     {
  235.       /* Replace the port in the descriptor cell
  236.          with the newly reauthenticated port.  */
  237.  
  238.       if (d->ctty.port != MACH_PORT_NULL &&
  239.           ! __io_reauthenticate (d->ctty.port, _hurd_pid) &&
  240.           ! __USEPORT (AUTH, __auth_user_authenticate (port,
  241.                                d->ctty.port,
  242.                                _hurd_pid,
  243.                                &newctty)))
  244.         _hurd_port_set (&d->ctty, newctty);
  245.  
  246.       _hurd_port_locked_set (&d->port, new);
  247.     }
  248.       else
  249.     /* Lost.  Leave this descriptor cell alone.  */
  250.     __spin_unlock (&d->port.lock);
  251.     }
  252.  
  253.   __mutex_unlock (&_hurd_dtable_lock);
  254.   HURD_CRITICAL_END;
  255. }
  256.  
  257. text_set_element (_hurd_reauth_hook, reauth_dtable);
  258.